package asteroids.model.programs;

import java.util.List;

import asteroids.model.SpaceObject;
import asteroids.model.programs.Kind.KindOfExpression;
import asteroids.model.programs.binaryexpression.Addition;
import asteroids.model.programs.binaryexpression.And;
import asteroids.model.programs.binaryexpression.Division;
import asteroids.model.programs.binaryexpression.Equality;
import asteroids.model.programs.binaryexpression.GreaterThan;
import asteroids.model.programs.binaryexpression.Multiplication;
import asteroids.model.programs.binaryexpression.Or;
import asteroids.model.programs.binaryexpression.Substraction;
import asteroids.model.programs.parsing.ProgramFactory;
import asteroids.model.programs.statements.AssignmentStatement;
import asteroids.model.programs.statements.FireStatement;
import asteroids.model.programs.statements.Foreach;
import asteroids.model.programs.statements.If;
import asteroids.model.programs.statements.PrintStatement;
import asteroids.model.programs.statements.Sequence;
import asteroids.model.programs.statements.SkipStatement;
import asteroids.model.programs.statements.Statement;
import asteroids.model.programs.statements.ThrusterStatement;
import asteroids.model.programs.statements.TurnStatement;
import asteroids.model.programs.statements.While;
import asteroids.model.programs.unaryexpression.Coordinate;
import asteroids.model.programs.unaryexpression.Cosinus;
import asteroids.model.programs.unaryexpression.Not;
import asteroids.model.programs.unaryexpression.RadiusOfEntity;
import asteroids.model.programs.unaryexpression.Sinus;
import asteroids.model.programs.unaryexpression.SquareRoot;
import asteroids.model.programs.zeroaryexpression.DirectionOfEntity;
import asteroids.model.programs.zeroaryexpression.Self;

@SuppressWarnings("rawtypes")
public class ProgramFactoryImpl implements ProgramFactory<Expression,Statement,Kind> {

	@Override
	public Literal<Double> createDoubleLiteral(int line, int column, double d) {
		return new Literal<Double>(d);
	}

	@Override
	public Literal<Boolean> createBooleanLiteral(int line, int column, boolean b) {
		return new Literal<Boolean>(b);
	}

	@Override
	public And createAnd(int line, int column, Expression e1, Expression e2) {
		return new And(e1,e2);
	}

	@Override
	public Or createOr(int line, int column, Expression e1, Expression e2) {
		return new Or(e1,e2);
	}

	@Override
	public Not createNot(int line, int column, Expression e) {
		return new Not(e);
		
	}

	@Override
	public Literal<SpaceObject> createNull(int line, int column) {
		return Literal.NULL;
	}

	@Override
	public Self createSelf(int line, int column) {
			return new Self();
	}

	@Override
	public Coordinate createGetX(int line, int column, Expression e) {
		return new Coordinate(e,true,true);
	}

	@Override
	public Coordinate createGetY(int line, int column, Expression e) {
		return new Coordinate(e,true,false);
	}

	@Override
	public Coordinate createGetVX(int line, int column, Expression e) {
		return new Coordinate(e,false,true);
	}

	@Override
	public Coordinate createGetVY(int line, int column, Expression e) {
		return new Coordinate(e,false,false);
	}

	@Override
	public RadiusOfEntity createGetRadius(int line, int column, Expression e) {
		return new RadiusOfEntity(e);
	}

	@Override
	public GetGlobal createVariable(int line, int column, String name) {
		return new GetGlobal(name);
	}

	@Override
	public GreaterThan createLessThan(int line, int column, Expression e1, Expression e2) {
		return (new GreaterThan(e2,e1));
			
	}

	@Override
	public GreaterThan createGreaterThan(int line, int column, Expression e1, Expression e2) {
		return new GreaterThan(e1,e2);
	}

	@Override
	public Or createLessThanOrEqualTo(int line, int column, Expression e1,
			Expression e2) {
		   return new Or(new Equality(e1,e2),(new GreaterThan(e2,e1)));
	}

	@Override
	public Or createGreaterThanOrEqualTo(int line, int column, Expression e1,
			Expression e2) {
		return new Or(new Equality(e1,e2),new GreaterThan(e1,e2));
	}

	@Override
	public Equality createEquality(int line, int column, Expression e1, Expression e2) {
		return new Equality(e1,e2);
	}

	@Override
	public Not createInequality(int line, int column, Expression e1, Expression e2) {
		return new Not(new Equality(e1,e2));
	}

	@Override
	public Addition createAdd(int line, int column, Expression e1,Expression e2) {
		return new Addition(e1,e2);
	}

	@Override
	public Substraction createSubtraction(int line, int column, Expression e1, Expression e2) {
		return new Substraction(e1,e2);
	}

	@Override
	public Multiplication createMul(int line, int column, Expression e1, Expression e2) {
		return new Multiplication(e1,e2);
	}

	@Override
	public Division createDivision(int line, int column, Expression e1, Expression e2) {
		return  new Division(e1,e2);
	}

	@Override
	public SquareRoot createSqrt(int line, int column, Expression e) {
		return new SquareRoot(e);
	}

	@Override
	public DirectionOfEntity createGetDirection(int line, int column) {
		return new DirectionOfEntity();
	}

	@Override
	public Sinus createSin(int line, int column, Expression e) {
		return new Sinus(e);
	}

	@Override
	public Cosinus createCos(int line, int column, Expression e) {
		return new Cosinus(e);
	}
	

	@Override
	public Statement createEnableThruster(int line, int column) {
		return new ThrusterStatement(true);
	}

	@Override
	public Statement createDisableThruster(int line, int column) {
		return new ThrusterStatement(false);
	}

	@Override
	public Statement createFire(int line, int column) {
		return new FireStatement();
	}

	@Override
	public Statement createSkip(int line, int column) {
		return new SkipStatement();
	}

	@Override
	public Statement createTurn(int line, int column, Expression angle) {
		return new TurnStatement(angle);
	}

	@Override
	public Statement createAssignment(int line, int column, String variable,
			Expression rhs) {
		return new AssignmentStatement(variable, rhs);
	}

	@Override
	public Statement createIf(int line, int column, Expression condition,
			Statement then, Statement otherwise) {
		return new If(condition, then, otherwise);
	}

	@Override
	public Statement createWhile(int line, int column, Expression condition,
			Statement body) {
		return new While(condition, body);
	}

	@Override
	public Statement createForeach(int line, int column,
			asteroids.model.programs.parsing.ProgramFactory.ForeachType type,
			String variableName, Statement body) {
		return new Foreach(type, variableName, body);
	}

	@Override
	public Statement createSequence(int line, int column,
			List<Statement> statements) {
		return new Sequence(statements);
	}

	@Override
	public Statement createPrint(int line, int column, Expression e) {
		return new PrintStatement(e);
	}

	@Override
	public Kind createDoubleType() {
		return new Kind(KindOfExpression.Double);
	}

	@Override
	public Kind createBooleanType() {
		return new Kind(KindOfExpression.Boolean);
	}

	@Override
	public Kind createEntityType() {
		return new Kind(KindOfExpression.Entity);
	}



	
	

}
